define(
  [
    'dojo/_base/declare',
    'dojo/on',
    'dojo/dom',
    'dojo/_base/lang',
    'dojo/dom-construct'
  ],
  function(declare, on, dom, lang, domConstruct)
  {
    return declare([],
      {
        classCode: 'DiceDistributionGenerator',
        
        constructor:function(args)
        {
          console.log(this.classCode, "I'm in constructor", this.classCode);
        },
        
        postscript:function()
        {
          console.log(this.classCode, "I'm in postscript", this.classCode);
        },
        
        setup:function(opt)
        {
          this.faces = opt.faces;
          this.dicesNumber = opt.dicesNumber;
          var lowestFace = this.faces[0];
          var highestFace = this.faces[this.faces.length - 1];
          
          var minValue = lowestFace * this.dicesNumber;
          var maxValue = highestFace * this.dicesNumber;
          var deltaValue = maxValue-minValue;
          
          this.valueMap = [];
          for(var value=0; value<=deltaValue; value++)
          {
            this.valueMap[value] = 0;
          }
          
        },
        
        startCalculateDistribution:function()
        {
          //this.res = this._calculateDistribution({diceNumber: this.dicesNumber});
          this.res = this._calculateDistribution({diceNumber: this.dicesNumber});
        },
        
        _calculateDistribution2:function(params)
        {
          this.res = 
          {
            minValue: 0,
            maxValue: 0,
            totalCombination: 0,
            distribution: []
          };
          
          this.res.minValue = this.faces[0] * params.diceNumber;
          this.res.maxValue = this.faces[this.faces.length - 1] * params.diceNumber;
          this.res.totalCombination = Math.pow(this.faces.length, params.diceNumber);
          
          var step = 100/this.res.totalCombination;
          
          for(var i=0; i<this.faces.length; i++)
          {
            for(var j=0; j<this.faces.length; j++)
            {
              var sum = i+j;
              this.res.distribution[sum] = this.res.distribution[sum] ? this.res.distribution[sum] + step : step;
            }
          }
          
          return this.res;
        },
        
        printRes:function()
        {
          console.log("Distributions:");
          this.res.distribution.forEach(lang.hitch(this,function(value, i)
            {
              console.log((i+this.res.minValue)+": "+value);
            }));
        },
        
        getData:function()
        {
          if(!this.data)
          {
            var data = [];
            
            this.res.distribution.forEach(lang.hitch(this,function(value, i)
            {
              /*
              x = distr / total
              */
              data[i] = 
              {
                sum: i+this.res.minValue,
                distribution: value / this.res.totalCombination
              };
            }));
            
            this.data = data;
          }
          
          return this.data;
        },
        
        _calculateDistribution:function(params)
        {
          var res = 
          {
            minValue: 0,
            maxValue: 0,
            totalCombination: 0,
            distribution: []
          };
          var value=0;
          var lowestFace = this.faces[0];
          var highestFace = this.faces[this.faces.length - 1];
          var minValue = lowestFace*params.diceNumber;
          var maxValue = highestFace*params.diceNumber;
          var deltaValue = maxValue-minValue;
          
          res.minValue = minValue;
          res.maxValue = maxValue;
          res.distribution = [];
          
          if(params.diceNumber === 1) // caso base
          {
            res.totalCombination = this.faces.length;
            this.faces.forEach(function(faceI)
              {
                faceI -= minValue;
                res.distribution[faceI] = 1;
              });
            //for(var i=0; i<this.faces.length; i++)
            //{
            //  var faceI = this.face[i];
            //  res.distribution[faceI] = 1;
            //}
          }
          else // chiamata ricorsiva
          {
            res.totalCombination = Math.pow(this.faces.length, params.diceNumber);
            var subRes = this._calculateDistribution({diceNumber:params.diceNumber-1});
            for(value=0; value<subRes.distribution.length; value++)
            {
              var actualValue = value + subRes.minValue;
              var actualDistr = subRes.distribution[value];
              for(var face=0; face<this.faces.length; face++)
              {
                var faceVal = this.faces[face];
                var newValue = actualValue + faceVal - minValue;
                
                var newDistribution = res.distribution[newValue] || 0;
                newDistribution += actualDistr;
                
                res.distribution[newValue] = newDistribution;
              }
            }
          }
          
          return res;
        },
        
        endOfLib:null
      });
  });